#ifndef DSPSIMULATOR_PARSER_H
#define DSPSIMULATOR_PARSER_H

#include <memory>
#include <simulatorV1/lexer/lexer.h>
#include <simulatorV1/ast/astnode.h>
#include <simulatorV1/ast/programNode.h>
#include <simulatorV1/ast/functionNode.h>
#include <simulatorV1/ast/regNode.h>
#include <simulatorV1/ast/constantNode.h>

/**
 * 语法分析使用自顶向下的LL(1)分析法分析用户输入的命令
 */
class Parser {
private:
    std::unique_ptr<Lexer> m_lexer; // 词法分析器

    std::shared_ptr<Token> m_look; // 当前分析的token

    std::shared_ptr<ProgramNode> m_programNode; // 分析当前用户输入的命令得到的结果

    // program = functions | e
    std::shared_ptr<ProgramNode> parseProgram();

    // functions = function functions
    std::vector<std::shared_ptr<FunctionNode>> parseFunctions();

    // function =  funcName funcTail
    std::shared_ptr<FunctionNode> parseFunction();

    // funcName =  id
    std::string parseFuncName();

    // funcTail = ; | (para)
    std::vector<std::shared_ptr<AstNode>> parseFuncTail();

    // para = paraData paraList | e
    std::vector<std::shared_ptr<AstNode>> parsePara();

    // paraList = ,paraData paraList | e
    std::vector<std::shared_ptr<AstNode>> parseParaList();

    // paraData = number | reg
    std::shared_ptr<AstNode> parseParaData();

    //reg = A0-A31 | B0-B31
    std::shared_ptr<AstNode> parseReg();

    bool isMatchReg(); // 当前的m_look是否为寄存器token类

    void move(); // m_look更新为下一个token

    bool match(Tag need);   // 如果m_look的类型与need匹配，返回true，并将m_look更新为下一个token；否则返回false

public:
    Parser();

    ~Parser() = default;

    /**
     * 分析用户输入的命令
     * @param command 用户输入的命令
     */
    void analysis(std::string command);

    /**
     * @return 分析的结果
     */
    std::shared_ptr<ProgramNode> getProgramNode();
};

#endif //DSPSIMULATOR_PARSER_H
